<template>
  <div
    :style="{marginBottom: `${clearHeight ? 0 : (!config.backgroundColor && !config.backgroundBlur ? 0 : topAreaHeight + navBtnMarginX)}px`}">
    <!-- 导航栏背景 -->
    <div
      class="navigation-background w-full h-300rpx fixed top-0 left-0 transition duration-300"
      :class="config.backgroundBlur ? 'backdrop-filter backdrop-blur-10' : ''"
      :style="{
        height: `${topAreaHeight + navBtnMarginX}px`,
        backgroundColor: backgroundColor
      }">
    </div>
    <!-- 导航栏主体 -->
    <div
      class="navigation-bar w-screen fixed flex left-0"
      :style="{top: `${navigationTop}px`, height: `${navigationBarHeight}px`}">
      <div
        :style="{
          marginLeft: `${navBtnMarginX}px`,
          minWidth: `${config.isShowButton ? navBtnWidth : 0}px`
        }">
        <!-- 导航栏左侧胶囊按钮插槽 -->
        <slot name="button" v-if="unreadCount === 0 || config.hideBadge">
          <!-- 胶囊按钮模板 -->
          <div
            class="navigation-menu-button"
            :style="{width: `${navBtnWidth}px`}"
            v-if="config.isShowButton">
            <div
              class="navigation-menu-button-content flex"
              :style="{height: `${0.54 * navigationBarHeight}px`, margin: `${0.23 * navigationBarHeight}px 0`}">
              <div
                class="navigation-back wh-full flex flex-center text-center"
                @click="handleNavBtnClick(0)">
                <i class="fas fa-angle-left text-40rpx text-hex-000000" />
              </div>
              <div
                class="navigation-menu wh-full flex flex-center text-center"
                @click="handleNavBtnClick(1)">
                <i class="fas fa-house text-34rpx text-hex-000000" />
              </div>
            </div>
          </div>
        </slot>
        <!-- 存在未读消息时的胶囊按钮 -->
        <div
          class="navigation-menu-button h-full"
          :style="{width: `${navBtnWidth}px`}"
          v-if="config.isShowButton && !config.hideBadge && unreadCount !== 0">
          <div
            class="navigation-menu-button-content flex"
            :style="{
              height: `${0.54 * navigationBarHeight}px`,
              margin: `${0.23 * navigationBarHeight}px 0`,
            }">
            <div
              class="navigation-back wh-full flex flex-center text-center"
              @click="handleNavBtnClick(0)">
              <i class="fas fa-angle-left text-40rpx text-hex-000000" />
            </div>
            <div
              class="navigation-menu wh-full flex flex-center text-center"
              @click="handleNavBtnClick(2)">
              <i class="fas fa-message text-34rpx text-hex-000000" />
              <div
                class="badge-container w-0 h-0"
                v-if="unreadCount !== 0">
                <div class="badge w-30rpx h-30rpx relative -top-28rpx -left-18rpx text-center text-white text-18rpx">
                  {{ unreadCount }}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <!-- 导航栏标题 -->
      <div
        class="navigation-title h-full ml-10px text-36rpx text-black"
        v-show="props.titleText !== ''"
        :style="{
          width: `${windowWidth - 2 * navBtnWidth - 2 * navBtnMarginX - 20}px`,
          lineHeight: `${navigationBarHeight}px`,
          textAlign: `${isShowButton ? 'center' : 'left'}`,
          color: `${titleColor}`
        }">
        <slot name="title">
          <div class="truncate">{{ props.titleText }}</div>
        </slot>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
  import {useSystemStore} from '@/store'
  import {gotoPage} from '@/common/utils'

  interface NavigationBarProps {
    isShowButton?: boolean //是否显示左侧胶囊按钮（不显示时标题靠左显示）
    hideBadge?: boolean //是否隐藏消息提醒时的气泡提醒
    titleText?: string //标题内容，为空字符串时不显示标题
    titleColor?: string //标题字体颜色
    backgroundColor?: string //导航栏背景颜色，为空时背景颜色为透明，且导航栏不占高度
    backgroundBlur?: boolean //导航栏背景是否高斯模糊
    clearHeight?: boolean //是否清除导航栏所占高度
    customBackFunc?: Function | null //自定义导航栏返回按钮点击事件
  }

  const props = withDefaults(defineProps<NavigationBarProps>(), {
    isShowButton: true,
    hideBadge: false,
    titleText: '',
    titleColor: '#333333',
    backgroundColor: '',
    backgroundBlur: false,
    clearHeight: false,
    customBackFunc: null
  })
  const config = ref<NavigationBarProps>(JSON.parse(JSON.stringify(props)))

  const {
    windowWidth,
    navBtnWidth,
    navigationTop,
    navBtnMarginX,
    topAreaHeight
  } = storeToRefs(useSystemStore())
  const unreadMessageCount = ref(0)
  const navigationBarHeight = topAreaHeight.value - navigationTop.value

  // 背景颜色
  const backgroundColor = computed(() => {
    if (config.value.backgroundBlur) {
      return config.value.backgroundColor ?? 'rgba(255, 255, 255, 0.8)'
    } else {
      return !config.value.backgroundColor ? 'transparent' : config.value.backgroundColor ?? ''
    }
  })

  /**
   * 手动设置导航栏配置，用于动态更改导航栏
   * @param options 配置选项，同Props
   */
  function setNavigationBar(options: NavigationBarProps) {
    if (Object.getOwnPropertyNames(options).length) {
      config.value = Object.assign(config.value, options)
    }
  }

  defineExpose({setNavigationBar, navigationBarHeight})

  type NavBtnClickType = 0 | 1 | 2 //点击触发的类型，0:返回, 1:跳转首页, 2:跳转消息页

  //导航栏胶囊按钮点击事件
  const handleNavBtnClick = (type: NavBtnClickType) => {
    if (type === 0) {
      if (typeof props.customBackFunc === 'function') {
        //执行自定义事件
        props.customBackFunc()
      } else {
        uni.navigateBack({
          fail: () => gotoHome()
        })
        reset()
      }
    } else if (type === 1) {
      gotoHome()
      reset()
    }
  }

  //跳转首页
  const gotoHome = () => {
    gotoPage('/pages/index/index', 'redirectTo').catch(err => {
      console.error(err)
    })
  }

  //重置导航栏
  const reset = () => {
    setTimeout(() => {
      config.value = {
        isShowButton: true,
        hideBadge: false,
        titleText: '',
        titleColor: '#333333',
        backgroundColor: '',
        backgroundBlur: false,
        customBackFunc: null
      }
    }, 1000)
  }

  //未读消息数量
  const unreadCount = computed(() => unreadMessageCount.value > 99 ? 99 : unreadMessageCount.value)
</script>

<style scoped lang="scss">
  @import 'navigation-bar';
</style>
